<template>
    <h1>{{ title }}</h1>
    <p>count: {{ count }}</p>
    <p>doubleCount: {{doubleCount}}</p>
    <p>state.a: {{ state.a }}</p>
    <p>state.b: {{ state.b }}</p>
    <p>state.c.c: {{ state.c.c }}</p>

    <button @click="handleClick">+2</button>
    <button @click="changeA">Change A</button>
    <button @click="changeB">Change B</button>
    <button @click="changeC">Change C</button>
</template>

<script setup lang="ts">
import com from "./com.vue";
import { useRoute } from "vue-router";
import { computed, reactive, ref, watch } from "vue";

const route = useRoute();

const title = ref("watchComputed");

if (route.meta && route.meta.title) {
    title.value = route.meta.title as string;
}

const count = ref(2);

const doubleCount = computed((oldVal, b, c) => {
    console.log(oldVal, b, c);
    return count.value * 2;
});

const handleClick = () => {
    count.value += 2;
};

watch(count, (newVal, oldVal) => {
    console.log("newVal:", newVal);
    console.log("oldVal:", oldVal);
});

const state = reactive({ a: 1, b: 2, c: { c: 3 } });

const changeA = () => {
    state.a++;
};

const changeB = () => {
    state.b++;
};

const changeC = () => {
    state.c.c++;
};

watch(
    () => state.a,
    (newVal, oldVal) => {
        console.log("state.a newVal:", newVal);
        console.log("state.a oldVal:", oldVal);
    },
    {
        deep: true,
        immediate: true,
        // 使用 flush: "post" 确保在 DOM 更新后执行
        // 使用 flush: "pre" 确保在 DOM 更新前执行
        // 使用 flush: "sync" 确保在当前 tick 同步执行
        flush: "sync",
    }
);

watch([() => state.a, () => state.b], ([newA, newB], [oldA, oldB]) => {
    console.log("state.a newA:", newA, "state.a oldA:", oldA);
    console.log("state.b newB:", newB, "state.b oldB:", oldB);
});

watch(
    state.a,
    (newVal, oldVal) => {
        console.log("newVal-state.a:", JSON.stringify(newVal));
        console.log("oldVal-state.a:", JSON.stringify(oldVal));
    },
    { deep: true, immediate: true }
);

watch(state, (newVal, oldVal) => {
    console.log("newVal-state:", JSON.stringify(newVal));
    console.log("oldVal-state:", JSON.stringify(oldVal));
});

watch(
    state,
    (newVal, oldVal) => {
        console.log("newVal-state-deep:", JSON.stringify(newVal));
        console.log("oldVal-state-deep:", JSON.stringify(oldVal));
    },
    { deep: true }
);
</script>

<style scoped></style>
